package utils

import "fmt"

var (
	codesMess = [32]byte{'F', 'L', 'G', 'W', '5', 'X', 'C', '3',
		'9', 'Z', 'M', '6', '7', 'Y', 'R', 'T', '2', 'H', 'S', '8', 'D', 'V', 'E', 'J', '4', 'K',
		'Q', 'P', 'U', 'A', 'N', 'B'}
)

const (
	charsLength = 32
	codeLen     = 6
	slat        = int(1234561)
	prime1      = 3
	prime2      = 11
)

func IdEncode(id int) (code string, err error) {
	if id > 9999999 {
		err = fmt.Errorf("id must small than 9999999")
		return
	}
	var codeArr []byte
	//补位
	id = id*prime1 + slat
	//将 id 转换成32进制的值
	b := make([]int, codeLen)
	//32进制数
	b[0] = id
	for i := int(0); i < codeLen-1; i++ {
		b[i+1] = b[i] / charsLength
		b[i] = (b[i] + i*b[0]) % charsLength
	}
	b[5] = (b[0] + b[1] + b[2] + b[3] + b[4]) * prime1 % charsLength

	codeIndexArray := [codeLen]int{}
	for i := int(0); i < codeLen; i++ {
		codeIndexArray[i] = b[i*prime2%codeLen]
	}
	for _, index := range codeIndexArray {
		codeArr = append(codeArr, codesMess[index])
	}
	return fmt.Sprintf("%s", codeArr), nil
}

func DecodeId(code string) (id int, err error) {
	if len(code) != codeLen {
		err = fmt.Errorf("code length error, must be %d", codeLen)
		return
	}
	codeArr := make([]int, codeLen)
	for i := int(0); i < codeLen; i++ {
		codeSplit := code[i]
		index := findIndex(codeSplit)
		if index == -1 {
			err = fmt.Errorf("char not found")
			return
		}
		codeArr[i*prime2%codeLen] = int(index)
	}
	b := [codeLen]int{}
	for i := int(codeLen - 2); i >= 0; i-- {
		b[i] = (codeArr[i] - codeArr[0]*i + charsLength*i) % charsLength
	}
	for i := codeLen - 2; i >= 0; i-- {
		id += b[i]
		if i > 0 {
			id *= charsLength
		} else {
			id *= 1
		}
	}
	return (id - slat) / prime1, nil
}

func findIndex(char uint8) int {
	for index, _ := range codesMess {
		if char == codesMess[index] {
			return index
		}
	}
	return -1
}
